#include "StdAfx.h"
#include "Map.h"

#include "Object.h"
#include "Tile.h"

Map::Map(void)
{
}

Map::~Map(void)
{
}

Tile* Map::get_tile( unsigned int x, unsigned int y, unsigned int z )
{
	return get_tile(Vector3D<unsigned int>(x, y, z));
}

Tile* Map::get_tile( const Vector3D<unsigned int>& pos )
{
	TILE_MAP::iterator iter = Tiles.find(make_index(pos));
	if (iter != Tiles.end())
	{
		return iter->second;
	}
	else
	{
		return NULL;
	}
}
bool Map::move_to( Object& Obj, const Vector3D<unsigned int>& Dest )
{
	TILE_MAP::iterator IterPos = Tiles.find(make_index(Obj.get_pos()));
	TILE_MAP::iterator IterDest = Tiles.find(make_index(Dest));
	if (IterPos == Tiles.end() || IterDest == Tiles.end())
	{
		// Boundray, inaccessible.
		return true;
	}

	return IterDest->second->hit(Obj);
}

unsigned int Map::make_index( const Vector3D<unsigned int>& pos ) const
{
	Vector3D<unsigned int> newpos(pos);
	newpos.set_x(pos.get_x() / 32);
	newpos.set_y(pos.get_y() / 32);
	newpos.set_z(pos.get_z() / 32);
	unsigned char
		a0 = newpos.get_x() & 0x000000FF,
		a1 = newpos.get_x() & 0x0000FF00 >> 8,
		a2 = newpos.get_x() & 0x00FF0000 >> 16,
		a3 = newpos.get_x() & 0xFF000000 >> 24,
		b0 = newpos.get_y() & 0x000000FF,
		b1 = newpos.get_y() & 0x0000FF00 >> 8,
		b2 = newpos.get_y() & 0x00FF0000 >> 16,
		b3 = newpos.get_y() & 0xFF000000 >> 24,
		c0 = newpos.get_z() & 0x000000FF,
		c1 = newpos.get_z() & 0x0000FF00 >> 8,
		c2 = newpos.get_z() & 0x00FF0000 >> 16,
		c3 = newpos.get_z() & 0xFF000000 >> 24;

	return ((a0 ^ b1 ^ c2) << 24)
		| ((a1 ^ b2 ^ c3) << 16)
		| ((a2 ^ b3 ^ c0) << 8)
		|  (a3 ^ b0 ^ c1);
}